import javax.swing.plaf.TableHeaderUI;
import java.util.TreeMap;
import java.util.concurrent.BlockingDeque;

/**
 * Created with IntelliJ IDEA.
 * Description:多线程下的为什么会引起安全问题
 * 1根本原因:处理机对线程的调度是无序的并且会发生抢占式执行
 * 2代码结构  线程 并发执行 同时对同一对象的成员变量就行修改时 就会发生多线程安全问题
 * 3.多线程的操作本身不是原子性的 会有多条指令
 * User:岁亮亮
 * Date:2024-10-16
 * TIME:15:53
 */

public class ThreadDemo1 {
     public static int count = 0;
     public static Integer b = 12;
     public static Integer a = b;
     public static Integer c = 13;
     public static Integer d = 14;
    public static void main(String[] args) throws InterruptedException {
       Thread t1 = new Thread(() ->{
          synchronized (d){
              try {
                  Thread.sleep(1000);
              } catch (InterruptedException e) {
                  throw new RuntimeException(e);
              }
              a = c;
              for(int i = 0 ; i < 50000000; i++){
                  synchronized (a){

                      count++;
                  }
              }
          }
       });
       Thread t2 = new Thread(() ->{

           synchronized (a){
               try {
                   Thread.sleep(1000);
               } catch (InterruptedException e) {
                   throw new RuntimeException(e);
               }

               for (int i = 0; i < 50000000; i++) {
                  synchronized (d){
                      count++;

                  }
              }
          }
       });
       t1.start();
       t2.start();
        /***
         * t1 和t2 线程 并发执行 同时对同一对象的成员变量就行修改时 就会发生多线程安全问题
         * 根本原因 : 处理机对线程的调度是无序的并且会发生抢占式执行 在执行t1时 还没执行完 t2线程就又开始执行
         * 执行count++时 有三条指令要cpu 去执行
         * load 从内存中读取指令到cpu寄存器中
         * add 执行加1操作
         * save 将寄存器的值刷新到内存中
         * 由于线程的调度时无序的 可能t1 在执行时刚把load 和add操作完 t2开始执行load指令将未更新的值读到cou上执行加1操作
         * 这时就引起 少执行加1 操作 当然还有很多种不同的情况

         */
       t1.join();
       t2.join();
        System.out.println(count);

    }
}
